/*
 * @Project Name: 11
 * @File Name: CustomServiceGenerate.java
 * @Package Name: org.mybatis.generator.plugins
 * @Date: 2017年5月31日下午5:42:21
 * @Creator: wangyulong-910
 * @line------------------------------
 * @修改人:
 * @修改时间:
 * @修改内容:
 */

package org.amado.generator.plugins;

import org.amado.generator.util.DateUtil;
import org.mybatis.generator.api.CommentGenerator;
import org.mybatis.generator.api.GeneratedJavaFile;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.*;
import org.mybatis.generator.config.PropertyRegistry;

import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

/**
 * TODO
 * @author wangyulong-910
 * @date 2017年5月31日下午5:42:21
 * @see
 */
public class ServiceGeneratePlugin extends PluginAdapter {
	private static final String MAPPER = "mapper";
	private String servicePackage;
	private String author;
	@Override
	public boolean validate(List<String> warnings) {
		return true;
	}
	@Override
    public void setProperties(Properties properties) {
        super.setProperties(properties);
        servicePackage = properties.getProperty("servicePackage");
        author = properties.getProperty("author");
    }
	@Override
	public List<GeneratedJavaFile> contextGenerateAdditionalJavaFiles(IntrospectedTable introspectedTable) {
		List<CompilationUnit> unitList = new ArrayList<>();
		unitList.add(getServiceCompilationUnits(introspectedTable));
		unitList.add(getServiceImplCompilationUnits(introspectedTable));
		List<GeneratedJavaFile> answer = new ArrayList<GeneratedJavaFile>();
		for (CompilationUnit compilationUnit : unitList) {
			GeneratedJavaFile gjf = new GeneratedJavaFile(compilationUnit,
					context.getJavaModelGeneratorConfiguration().getTargetProject(),
					context.getProperty(PropertyRegistry.CONTEXT_JAVA_FILE_ENCODING), context.getJavaFormatter());
			answer.add(gjf);
		}
		return answer;
	}
	public CompilationUnit getServiceImplCompilationUnits(IntrospectedTable introspectedTable) {
		CommentGenerator commentGenerator = context.getCommentGenerator();
		String recordType = introspectedTable.getBaseRecordType();
		String serviceName = introspectedTable.getBaseRecordType().substring(recordType.lastIndexOf("."));
		FullyQualifiedJavaType serviceNameType = new FullyQualifiedJavaType(servicePackage+serviceName+"Service");
		FullyQualifiedJavaType serviceImplNameType = new FullyQualifiedJavaType(servicePackage+".impl"+serviceName+"ServiceImpl");
		FullyQualifiedJavaType autowiredNameType = new FullyQualifiedJavaType("org.springframework.beans.factory.annotation.Autowired");
		FullyQualifiedJavaType serviceAnnoationNameType = new FullyQualifiedJavaType("org.springframework.stereotype.Service");
		FullyQualifiedJavaType baseRecordType =  new FullyQualifiedJavaType(recordType);
		FullyQualifiedJavaType commonPageVoType =  new FullyQualifiedJavaType("com.github.pagehelper.PageInfo<"+recordType+">");
		FullyQualifiedJavaType commonPageVoShortType =  new FullyQualifiedJavaType("PageInfo<"+recordType+">");
		TopLevelClass classz = new TopLevelClass(serviceImplNameType); 
		classz.setVisibility(JavaVisibility.PUBLIC);
		classz.addJavaDocLine("/**"); //$NON-NLS-1$
		String remarks = introspectedTable.getRemarks();
		String[] remarkLines = remarks.split(System.getProperty("line.separator")); //$NON-NLS-1$
		for (String remarkLine : remarkLines) {
			classz.addJavaDocLine(" * " + remarkLine); //$NON-NLS-1$
		}
		classz.addJavaDocLine(" * @author " + author); //$NON-NLS-1$
		classz.addJavaDocLine(" * @date " + DateUtil.getDateStr()); //$NON-NLS-1$
		classz.addJavaDocLine(" */"); //$NON-NLS-1$
		
		FullyQualifiedJavaType  mapperType = new FullyQualifiedJavaType(introspectedTable.getMyBatis3JavaMapperType());
		
		addMapperField(classz, mapperType);
		
		//add
		Method method = new Method();
		method.setVisibility(JavaVisibility.PUBLIC);
		method.setName("insert"); //$NON-NLS-1$
		method.addParameter(new Parameter(baseRecordType, "record")); //$NON-NLS-1$
		method.addBodyLine(MAPPER+".insert(record);");
		method.addAnnotation("@Override");
		commentGenerator.addGeneralMethodComment(method, introspectedTable);
		
		classz.addMethod(method);
		
		//update
		method = new Method();
		method.setVisibility(JavaVisibility.PUBLIC);
		method.addParameter(new Parameter(baseRecordType, "record")); //$NON-NLS-1$
		method.setName("updateById"); //$NON-NLS-1$
		method.addBodyLine(MAPPER+".updateByPrimaryKeySelective(record);");
		method.addAnnotation("@Override");
		classz.addMethod(method);
		commentGenerator.addGeneralMethodComment(method, introspectedTable);
		
		//deleteById
		method = new Method();
		method.setVisibility(JavaVisibility.PUBLIC);
		method.setName("deleteById"); //$NON-NLS-1$
		method.addParameter(new Parameter(new FullyQualifiedJavaType(introspectedTable.getPrimaryKeyColumns().get(0).getFullyQualifiedJavaType().getShortName()), "id")); //$NON-NLS-1$
		method.addBodyLine(MAPPER+".deleteByPrimaryKey(id);");
		method.addAnnotation("@Override");
		classz.addMethod(method);
		commentGenerator.addGeneralMethodComment(method, introspectedTable);
		
		//getById
		method = new Method();
		method.setVisibility(JavaVisibility.PUBLIC);
		method.setReturnType(FullyQualifiedJavaType
				.getBooleanPrimitiveInstance());
		method.setName("getById"); //$NON-NLS-1$
		method.setReturnType(baseRecordType);
		method.addParameter(new Parameter(new FullyQualifiedJavaType(introspectedTable.getPrimaryKeyColumns().get(0).getFullyQualifiedJavaType().getShortName()), "id")); //$NON-NLS-1$
		method.addBodyLine("return "+MAPPER+".selectByPrimaryKey(id);");
		method.addAnnotation("@Override");
		classz.addMethod(method);
		commentGenerator.addGeneralMethodComment(method, introspectedTable);
		
		//list
		method = new Method();
		method.setVisibility(JavaVisibility.PUBLIC);
		method.setName("list"); //$NON-NLS-1$
		FullyQualifiedJavaType listJavaType = new FullyQualifiedJavaType("com.amado.commons.PageRequest");
		method.addParameter(new Parameter(listJavaType, "pageRequest")); //$NON-NLS-1$
		method.setReturnType(commonPageVoShortType);
		method.addBodyLine("//TODO");

		String exampleType = introspectedTable.getExampleType();
		FullyQualifiedJavaType exampleTypeFullyQualifiedJavaType = new FullyQualifiedJavaType(exampleType);
		method.addBodyLine(exampleTypeFullyQualifiedJavaType.getShortName()+" example = new "+exampleTypeFullyQualifiedJavaType.getShortName()+"();");
		method.addBodyLine("if (pageRequest.getOrderBy()!=null) {");
		method.addBodyLine("StringBuilder stringBuilder = new StringBuilder();");
		method.addBodyLine("stringBuilder.append(pageRequest.getOrderBy());");
		method.addBodyLine("if (pageRequest.getSort()!=null) {");
		method.addBodyLine("stringBuilder.append(\" \").append(pageRequest.getSort());");
		method.addBodyLine("}");
		method.addBodyLine("example.setOrderByClause(stringBuilder.toString());");
		method.addBodyLine("}");
		method.addBodyLine("return PageHelper.startPage(pageRequest.getOffset(),pageRequest.getLimit()).doSelectPageInfo(()->mapper.selectByExample(example));");
		method.addAnnotation("@Override");
		classz.addMethod(method);
		commentGenerator.addGeneralMethodComment(method, introspectedTable);


		classz.addImportedType(autowiredNameType);
		classz.addImportedType(serviceAnnoationNameType);
		classz.addImportedType(baseRecordType);
		classz.addImportedType(commonPageVoType);
		classz.addImportedType(listJavaType);
		classz.addImportedType(serviceNameType);
		classz.addImportedType(mapperType);
		classz.addImportedType(exampleTypeFullyQualifiedJavaType);
		classz.addSuperInterface(serviceNameType);
		classz.addAnnotation("@Service");
		return classz;
	}
	private void addMapperField(TopLevelClass classz, FullyQualifiedJavaType mapperType) {
		Field filed = new Field(MAPPER, mapperType);
		filed.addAnnotation("@Autowired");
		filed.setVisibility(JavaVisibility.PRIVATE);	
		classz.addField(filed);
	}
	public CompilationUnit getServiceCompilationUnits(IntrospectedTable introspectedTable) {
        CommentGenerator commentGenerator = context.getCommentGenerator();
        String recordType = introspectedTable.getBaseRecordType();
        String serviceName = introspectedTable.getBaseRecordType().substring(recordType.lastIndexOf("."));
        FullyQualifiedJavaType serviceNameType = new FullyQualifiedJavaType(servicePackage+serviceName+"Service");
        FullyQualifiedJavaType baseRecordType =  new FullyQualifiedJavaType(recordType);
        FullyQualifiedJavaType commonPageVoType =  new FullyQualifiedJavaType("com.github.pagehelper.PageInfo<"+recordType+">");
        FullyQualifiedJavaType commonPageVoShortType =  new FullyQualifiedJavaType("PageInfo<"+recordType+">");
        Interface interfaze = new Interface(serviceNameType); 
        interfaze.setVisibility(JavaVisibility.PUBLIC);
        /**
         * 收藏夹
         * @author wangyulong-910
         * @date 2017年6月1日下午2:25:26
         */
        
        interfaze.addJavaDocLine("/**"); //$NON-NLS-1$
		String remarks = introspectedTable.getRemarks();
		String[] remarkLines = remarks.split(System.getProperty("line.separator")); //$NON-NLS-1$
		for (String remarkLine : remarkLines) {
			interfaze.addJavaDocLine(" * " + remarkLine); //$NON-NLS-1$
			}
		interfaze.addJavaDocLine(" * @author " + author); //$NON-NLS-1$
		interfaze.addJavaDocLine(" * @date " + DateUtil.getDateStr()); //$NON-NLS-1$
		interfaze.addJavaDocLine(" */"); //$NON-NLS-1$
		
		
        //add
        Method method = new Method();
        method.setVisibility(JavaVisibility.PUBLIC);
        method.setName("insert"); //$NON-NLS-1$
        method.addParameter(new Parameter(baseRecordType, "record")); //$NON-NLS-1$
        commentGenerator.addGeneralMethodComment(method, introspectedTable);
        interfaze.addMethod(method);

        //update
        method = new Method();
        method.setVisibility(JavaVisibility.PUBLIC);
        method.addParameter(new Parameter(baseRecordType, "record")); //$NON-NLS-1$
        method.setName("updateById"); //$NON-NLS-1$
        commentGenerator.addGeneralMethodComment(method, introspectedTable);
        interfaze.addMethod(method);
        
        //deleteById
        method = new Method();
        method.setVisibility(JavaVisibility.PUBLIC);
        method.setName("deleteById"); //$NON-NLS-1$
        method.addParameter(new Parameter(new FullyQualifiedJavaType(introspectedTable.getPrimaryKeyColumns().get(0).getFullyQualifiedJavaType().getShortName()), "id")); //$NON-NLS-1$
        commentGenerator.addGeneralMethodComment(method, introspectedTable);
        interfaze.addMethod(method);
        
        //getById
        method = new Method();
        method.setVisibility(JavaVisibility.PUBLIC);
        method.setReturnType(FullyQualifiedJavaType
                .getBooleanPrimitiveInstance());
        method.setName("getById"); //$NON-NLS-1$
        method.setReturnType(baseRecordType);
        method.addParameter(new Parameter(new FullyQualifiedJavaType(introspectedTable.getPrimaryKeyColumns().get(0).getFullyQualifiedJavaType().getShortName()), "id")); //$NON-NLS-1$
        commentGenerator.addGeneralMethodComment(method, introspectedTable);
        interfaze.addMethod(method);
        
        //list
        method = new Method();
        method.setVisibility(JavaVisibility.PUBLIC);
        method.setName("list"); //$NON-NLS-1$
        FullyQualifiedJavaType listJavaType = new FullyQualifiedJavaType("com.amado.commons.PageRequest");
        method.addParameter(new Parameter(listJavaType, "pageRequest")); //$NON-NLS-1$
        method.setReturnType(commonPageVoShortType);
        commentGenerator.addGeneralMethodComment(method, introspectedTable);
        interfaze.addMethod(method);
        interfaze.addImportedType(baseRecordType);
        interfaze.addImportedType(commonPageVoType);
        interfaze.addImportedType(listJavaType);
        return interfaze;
   }
}
